package com.ruolin.micro.gateway.server.metadata;

import cn.hutool.core.collection.CollectionUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.util.AntPathMatcher;

import java.util.*;

public class MethodRouteMetadata {
    private String name;
    private List<String> parameterTypes;
    private String returnType;
    private Pair<String[], String[]> pair;
    private int objectIndex;
    private int javaArgIndex;
    private String routePart;
    private String routePartAlias;
    private Map<String, Object> fieldMap = new LinkedHashMap<>();

    public List<String> getParameterTypes() {
        for (int i = 0; i < parameterTypes.size(); i++) {
            if (parameterTypes.get(i).contains("java.util.List")) {
                parameterTypes.set(i, "java.util.List");
            }
        }
        return parameterTypes;
    }

    public String[] getParameterTypeArray() {
        if (CollectionUtil.isNotEmpty(parameterTypes)) {
            return parameterTypes.toArray(new String[parameterTypes.size()]);
        }
        return new String[]{};
    }

    public int getTypeLen() {
        return parameterTypes.size();
    }

    public int getObjectIndex() {
        if (!getParameterTypes().isEmpty()) {
            for (int i = 0; i < parameterTypes.size(); i++) {
                if (getParameterTypes().get(i).startsWith("com.")) {
                    return i;
                }
            }
        }
        return -1;
    }

    public boolean hasJavaType() {
        if (!getParameterTypes().isEmpty()) {
            return getParameterTypes().stream().anyMatch(t -> t.startsWith("java"));
        }
        return false;
    }

    public boolean hasArrayType() {
        if (!getParameterTypes().isEmpty()) {
            return getParameterTypes().stream().anyMatch(t -> t.contains("java.util.List"));
        }
        return false;
    }

    public String getRoutePartAlias(){
      final StringBuilder routeBuilder = new StringBuilder(routePart);
      if (getObjectIndex() == -1  && !parameterTypes.isEmpty() ){
          for (String parameterType : parameterTypes) {
              routeBuilder.append("/{p}");
          }
      }

      return routeBuilder.toString();
    }

    public boolean match(String route){
        AntPathMatcher antPathMatcher = new AntPathMatcher();
        return antPathMatcher.match(getRoutePartAlias(), route);
    }


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setParameterTypes(List<String> parameterTypes) {
        this.parameterTypes = parameterTypes;
    }

    public String getReturnType() {
        return returnType;
    }

    public void setReturnType(String returnType) {
        this.returnType = returnType;
    }

    public Pair<String[], String[]> getPair() {
        return pair;
    }

    public void setPair(Pair<String[], String[]> pair) {
        this.pair = pair;
    }

    public void setObjectIndex(int objectIndex) {
        this.objectIndex = objectIndex;
    }

    public int getJavaArgIndex() {
        return javaArgIndex;
    }

    public void setJavaArgIndex(int javaArgIndex) {
        this.javaArgIndex = javaArgIndex;
    }

    public String getRoutePart() {
        return routePart;
    }

    public void setRoutePart(String routePart) {
        this.routePart = routePart;
    }

    public void setRoutePartAlias(String routePartAlias) {
        this.routePartAlias = routePartAlias;
    }

    public Map<String, Object> getFieldMap() {
        return fieldMap;
    }

    public void setFieldMap(Map<String, Object> fieldMap) {
        this.fieldMap = fieldMap;
    }
}